package com.lxm.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lxm.common.contants.BlogConstants;
import com.lxm.common.contants.CartConstants;
import com.lxm.common.contants.LikesConstants;
import com.lxm.common.contants.LxmCommentConstants;
import com.lxm.common.tools.ContentUtils;
import com.lxm.common.tools.ImgUrlUtils;
import com.lxm.common.tools.UserHolder;
import com.lxm.dto.BlogDTO;
import com.lxm.dto.Result;
import com.lxm.entity.Blog;
import com.lxm.entity.Login;
import com.lxm.mapper.BlogDao;
import com.lxm.service.BlogService;
import com.lxm.service.LikesService;
import com.lxm.service.LoginService;
import com.lxm.service.LxmCommentService;
import com.lxm.vo.BlogDraftDetailVO;
import com.lxm.vo.BlogPageVO;
import com.lxm.vo.BlogReleaseDetailVO;
import jakarta.annotation.Resource;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 发布表 服务实现类
 * </p>
 *
 * @author ${author}
 * @since 2024-10-02
 */
@Service
public class BlogServiceImpl extends ServiceImpl<BlogDao, Blog> implements BlogService {

    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private LikesService likesService;
    @Resource
    private LxmCommentService lxmCommentService;
    @Resource
    private LoginService loginService;

    /**
     * 新增文章
     *
     * @param blogDTO
     * @return
     */


    @Override
    public Result add(BlogDTO blogDTO) {
        // 填充用户id
        Blog blog = BeanUtil.copyProperties(blogDTO, Blog.class);
        blog.setUserId(UserHolder.getUser().getUserId());
        boolean isSuccess = save(blog);
        return isSuccess ? Result.ok() : Result.fail(BlogConstants.ADD_BLOG_FAIL);
    }

    /**
     * 删除文章 可以批量删除
     *
     * @param ids
     * @return Result
     */

    @Override
    public Result batchDelete(List<Long> ids) {
        Long userId = UserHolder.getUser().getUserId();
        if (CollUtil.isEmpty(ids)) return Result.fail(CartConstants.CART_DELETE_FAIL);
        boolean isSuccess = remove(new LambdaQueryWrapper<Blog>()
                .eq(Blog::getUserId, userId)
                .in(Blog::getBlogId, ids));
        return isSuccess ? Result.ok(BlogConstants.DELETE_BLOG_SUCCESS)
                : Result.fail(BlogConstants.DELETE_BLOG_FAIL);
    }

    /**
     * 根据用户id查询文章发布列表，这个用于用户查询自己的博客或者博主的其他博客
     *
     * @param userId
     * @return Result
     */


    @Override
    public Result listByUserId(Long userId, Integer current) {
        List<Blog> blogList = lambdaQuery()
                .eq(Blog::getUserId, userId)
                .orderByDesc(Blog::getCreateTime)
                // 只返回需要的字段,这里仅仅是简略展示需要的
                .select(Blog::getBlogId, Blog::getImg, Blog::getTitle
                        , Blog::getUserId, Blog::getLikeNum, Blog::getCreateTime)
                .page(new Page<>(current, BlogConstants.BLOG_PAGE_SIZE))
                .getRecords();
        if (CollUtil.isEmpty(blogList)) return Result.ok(blogList);
        // 将图片地址转化为封面地址,并且直返会封面地址
        List<BlogPageVO> blogPageVOS = blogList.stream()
                .map(this::getBlogPageVO)
                .collect(Collectors.toList());
        return Result.ok(blogPageVOS);
    }


    /**
     * 修改文章
     *
     * @param blogDTO
     * @return
     */

    @Override
    public Result updateBlog(BlogDTO blogDTO, Long blogId) {
        Long userId = UserHolder.getUser().getUserId();
        Blog blog = BeanUtil.copyProperties(blogDTO, Blog.class);
        boolean isSuccess = update(blog, new LambdaQueryWrapper<Blog>()
                .eq(Blog::getUserId, userId)
                .eq(Blog::getBlogId, blogId)
        );
        return isSuccess ? Result.ok() : Result.fail(BlogConstants.UPDATE_BLOG_FAIL);
    }

    /**
     * 按时间排序查询文章列表,用于首页返回
     *
     * @param current
     * @return Result
     */
    @Override
    public Result listByTime(Long current) {
        List<Blog> blogList = lambdaQuery()
                .orderByDesc(Blog::getCreateTime)
                .select(Blog::getBlogId, Blog::getImg, Blog::getTitle,
                        Blog::getUserId, Blog::getLikeNum, Blog::getCreateTime)
                .page(new Page<>(current, BlogConstants.BLOG_PAGE_SIZE))
                .getRecords();
        if (CollUtil.isEmpty(blogList)) return Result.ok(null);
        List<BlogPageVO> blogPageVOList = blogList
                .stream()
                .map(this::getBlogPageVO)
                .collect(Collectors.toList());
        return Result.ok(blogPageVOList);
    }

    @Override
    public Result getDetailBlogRelease(Long blogId) {
        // 查询博客信息
        Blog blog = lambdaQuery()
                .eq(Blog::getBlogId, blogId)
                .eq(Blog::getBlogStatus, BlogConstants.BLOG_RELEASE_STATUS)
                .select(Blog::getBlogId, Blog::getImg, Blog::getTitle, Blog::getUserId,
                        Blog::getContent, Blog::getLikeNum, Blog::getCommentNum,
                        Blog::getCreateTime, Blog::getUpdateTime)
                .one();
        if (BeanUtil.isEmpty(blog)) return Result.fail(BlogConstants.BLOG_NOT_EXIST);
        //本身就是通过分页浏览页进入的，不存在没有的情况
        BlogReleaseDetailVO blogReleaseDetailVO = BeanUtil.toBean(blog, BlogReleaseDetailVO.class);
        Login useInfo = loginService.getUserInfoLogin(blog.getUserId());
        //填充发表人的头像和昵称
        blogReleaseDetailVO.setNickName(useInfo.getNickName());
        blogReleaseDetailVO.setUserImg(useInfo.getIcon());
        // 将图片地址转化为图片列表
        blogReleaseDetailVO.setImg(ImgUrlUtils
                .parseImageUrlToList(blog.getImg()));
        // 查询评论列表
        blogReleaseDetailVO.setCommentList(lxmCommentService
                .getDetailCommentList(blogId, LxmCommentConstants.BLOG_TYPE, 1));
        boolean isLike = likesService.checkLike(blogId, LikesConstants.BLOG_LIKE);
        blogReleaseDetailVO.setIsLike(isLike);
        // 返回
        return Result.ok(blogReleaseDetailVO);
    }

    @Override
    public Result getDetailBlogDraftByME() {
        Long userId = UserHolder.getUser().getUserId();
        // 查询草稿列表
        List<Blog> blogList = lambdaQuery()
                .eq(Blog::getUserId, userId)
                .eq(Blog::getBlogStatus, BlogConstants.BLOG_DRAFT_STATUS)
                .select(Blog::getBlogId, Blog::getImg, Blog::getTitle,
                        Blog::getContent, Blog::getCreateTime, Blog::getUpdateTime)
                .list();
        //检查草稿是否为空
        if (CollUtil.isEmpty(blogList)) {
            return Result.fail(BlogConstants.NOT_DRAFT_BLOG);
        }
        // 将图片地址转化为图片列表
        List<BlogDraftDetailVO> blogDraftDetailVOS = blogList
                .stream()
                .map(blog -> {
                    BlogDraftDetailVO blogDraftDetailVO = BeanUtil.toBean(blog, BlogDraftDetailVO.class);
                    blogDraftDetailVO.setImg(ImgUrlUtils.parseImageUrlToList(blog.getImg()));
                    return blogDraftDetailVO;
                })
                .collect(Collectors.toList());
        return Result.ok(blogDraftDetailVOS);
    }

    @Override
    public Result getBlogTypeList() {
        Map<String, String> blogTypeMap = stringRedisTemplate.opsForHash()
                .entries(BlogConstants.BLOG_TYPE_KEY)
                .entrySet()
                .stream()
                .collect(Collectors.toMap(
                        entry -> entry.getKey().toString(),
                        entry -> entry.getValue().toString()
                ));
        return Result.ok(blogTypeMap);
    }

    @Override
    public Result listByType(Integer type, Long current) {
        List<Blog> blogList = lambdaQuery()
                .eq(Blog::getBlogType, type)
                .orderByDesc(Blog::getCreateTime)
                .select(Blog::getBlogId, Blog::getImg, Blog::getTitle,
                        Blog::getUserId, Blog::getLikeNum, Blog::getCreateTime)
                .page(new Page<>(current, BlogConstants.BLOG_PAGE_SIZE))
                .getRecords();
        if (CollUtil.isEmpty(blogList)) return Result.ok(null);
        List<BlogPageVO> blogPageVOList = blogList
                .stream()
                .map(this::getBlogPageVO)
                .collect(Collectors.toList());
        return Result.ok(blogPageVOList);
    }

    /**
     * 获取博客分页VO
     *
     * @param blog
     * @return BlogPageVO
     */
    @NotNull
    private BlogPageVO getBlogPageVO(Blog blog) {
        BlogPageVO blogPageVO = BeanUtil.toBean(blog, BlogPageVO.class);
        Login userInfoLogin = loginService.getUserInfoLogin(blog.getUserId());
        blogPageVO.setTitle(ContentUtils
                .getBriefEnd(blogPageVO.getTitle(), BlogConstants.BLOG_TITLE_BRIEF));
        // 设置博主信息
        blogPageVO.setNickName(userInfoLogin.getNickName());
        blogPageVO.setUserImg(userInfoLogin.getIcon());
        // 使用工具类解析图片地址，获取第一张图片(因为默认第一张是封面)
        blogPageVO.setImg(ImgUrlUtils.parseImageCoverUrl(blogPageVO.getImg()));
        return blogPageVO;
    }

}
